<template>
  <div class="async-components-container">
    <h2>异步组件 (Async Components)</h2>
    <p class="description">Vue 3中按需加载组件，提升应用性能和用户体验</p>
    
    <div class="demo-section">
      <div class="controls">
        <button @click="loadHeavyComponent" :disabled="isLoading">
          {{ isLoading ? '加载中...' : '加载重型组件' }}
        </button>
        <button @click="resetComponent">重置</button>
        <p class="status-message">{{ statusMessage }}</p>
      </div>
      
      <div class="component-area">
        <Suspense>
          <template #default>
            <AsyncComponent v-if="showComponent" />
            <div v-else class="placeholder">点击上方按钮加载异步组件</div>
          </template>
          <template #fallback>
            <div class="loading-state">
              <div class="spinner"></div>
              <p>组件正在加载，请稍候...</p>
            </div>
          </template>
        </Suspense>
      </div>
    </div>
    
    <div class="code-example">
      <h3>代码示例</h3>
      <CodeBlock 
        :code="codeExample" 
        language="vue" 
        :showLineNumbers="true" 
        :defaultDarkMode="false"
      />
    </div>
    
    <div class="features-list">
      <h3>主要特点</h3>
      <ul>
        <li>⚡ 按需加载组件，减少初始加载时间</li>
        <li>📦 支持代码分割，减少打包体积</li>
        <li>🔄 与Suspense配合使用，提供优雅的加载状态</li>
        <li>🛡️ 支持错误处理和超时控制</li>
        <li>📊 改善应用性能和用户体验</li>
      </ul>
    </div>
  </div>
</template>

<script setup>
import { ref, defineAsyncComponent } from 'vue'
import CodeBlock from '@components/CodeBlock.vue'

// 简单的加载状态组件
const LoadingComponent = {
  template: '<div class="loading">正在加载...</div>'
}

// 错误组件
const ErrorComponent = {
  template: '<div class="error">加载组件失败</div>'
}

// 定义异步组件
const AsyncComponent = defineAsyncComponent({
  // 加载函数
  loader: () => import('../../components/subcomponents/HeavyComponent.vue'),
  // 加载状态组件
  loadingComponent: LoadingComponent,
  // 错误组件
  errorComponent: ErrorComponent,
  // 延迟时间
  delay: 100,
  // 超时时间
  timeout: 5000
})

const showComponent = ref(false)
const isLoading = ref(false)
const statusMessage = ref('准备加载组件')

function loadHeavyComponent() {
  isLoading.value = true
  statusMessage.value = '开始加载重型组件...'
  showComponent.value = true
  
  // 模拟加载完成 - 实际加载状态由Suspense和异步组件管理
  setTimeout(() => {
    isLoading.value = false
    statusMessage.value = '组件加载完成'
  }, 2000)
}

function resetComponent() {
  showComponent.value = false
  statusMessage.value = '已重置，可以重新加载组件'
}

// 代码示例
const codeExample = `// Vue 3 异步组件定义
import { defineAsyncComponent } from "vue"

// 简单的加载状态组件
const LoadingComponent = {
  template: "<div>正在加载...</div>"
}

// 错误组件
const ErrorComponent = {
  template: "<div>加载组件失败</div>"
}

// 定义异步组件
const AsyncComponent = defineAsyncComponent({
  // 加载函数
  loader: () => import("../../components/subcomponents/HeavyComponent.vue"),
  
  // 加载状态组件
  loadingComponent: LoadingComponent,
  
  // 错误组件
  errorComponent: ErrorComponent,
  
  // 延迟显示加载组件(ms)
  delay: 200,
  
  // 超时时间(ms)
  timeout: 3000
})

// 在模板中使用Suspense包裹异步组件
// <Suspense>
//   <template #default>
//     <AsyncComponent />
//   </template>
//   <template #fallback>
//     <div>加载中...</div>
//   </template>
// </Suspense>`
</script>

<style scoped>
.async-components-container {
  max-width: 1000px;
  margin: 0 auto;
  padding: 20px;
  font-family: 'Arial', sans-serif;
}

h2 {
  color: #333;
  text-align: center;
  margin-bottom: 10px;
  font-size: 2rem;
}

.description {
  text-align: center;
  color: #666;
  margin-bottom: 30px;
  font-size: 1.1rem;
}

.demo-section {
  background-color: #f9f9f9;
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 30px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.controls {
  margin-bottom: 20px;
  text-align: center;
}

.controls button {
  padding: 10px 20px;
  margin: 0 10px;
  background-color: #3498db;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 1rem;
  transition: background-color 0.3s;
}

.controls button:hover:not(:disabled) {
  background-color: #2980b9;
}

.controls button:disabled {
  background-color: #95a5a6;
  cursor: not-allowed;
}

.status-message {
  margin-top: 15px;
  color: #7f8c8d;
}

.component-area {
  min-height: 300px;
  border: 2px dashed #bdc3c7;
  border-radius: 8px;
  padding: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: white;
}

.placeholder {
  color: #95a5a6;
  font-style: italic;
}

.loading-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #3498db;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 15px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.code-example {
  margin-bottom: 30px;
}

.code-block {
  background-color: #2d3748;
  border-radius: 6px;
  padding: 20px;
  overflow-x: auto;
}

pre {
  margin: 0;
}

code {
  color: #e2e8f0;
  font-family: 'Consolas', 'Monaco', monospace;
}

.features-list {
  background-color: #f9f9f9;
  border-radius: 8px;
  padding: 20px;
}

.features-list ul {
  list-style-type: none;
  padding-left: 0;
}

.features-list li {
  padding: 10px 0;
  padding-left: 20px;
  border-bottom: 1px solid #eee;
  position: relative;
}

.features-list li:last-child {
  border-bottom: none;
}
  
  .loading {
    text-align: center;
    color: #3498db;
    padding: 20px;
    font-size: 1.1rem;
  }
  
  .error {
    text-align: center;
    color: #e74c3c;
    padding: 20px;
    font-size: 1.1rem;
    background-color: #fee;
    border-radius: 4px;
  }
</style>